<?php

namespace lc\activity;

use app\controller\LotterySmsConfigController;
use lc\activity\model\LotterySmsConfig;
use lc\activity\model\LotterySmsLogs;
use lc\helpers\Curl;
use think\facade\Db;

/**
 * @desc    短信发送类
 * @package lc\activity
 */
class SmsAct
{
    /**
     * @var 短信活动 APPID
     */
    private $appId = 0;

    /**
     * @var 短信活动 APP_SECRET
     */
    private $appSecret = '';

    /**
     * @var 短信活动 PID
     */
    private $pid = 0;

    /**
     * @var 短信活动配置
     */
    private $config;
    private $time;

    public function __construct($appId, $appSecret)
    {
        $this->time      = time();
        $this->appId     = $appId;
        $this->appSecret = $appSecret;
    }

    public function setPid($pid)
    {
        $this->pid = $pid;
    }

    public function setAppid($appid)
    {
        $this->appId = $appid;
    }

    /**
     * @desc    发送短信
     * @param   string  $phone      手机号
     * @param   array   $contents   短信内容
     * @return  array
     */
    public function send(string $phone, array $contents)
    {
        if (!is_array($contents) || empty($contents)) {
            return ['status' => 0, 'msg' => '短信内容格式错误'];
        }
        if (!preg_match('/^(1(([356789][0-9])|(47)))\d{8}$/', trim($phone))) {
            return ['status' => 0, 'msg' => '电话号码格式错误'];
        }
        if ($check = $this->smsConfig()) {
            return $check;
        }

        $smsKey     = '6d66d9fd2f87d99e1b075f32ed1f781c';
        $url        = 'http://v.juhe.cn/sms/send';
        $tplValue   = '';
        foreach ($contents as $key => $value) {
            $tplValue .= "#{$key}#={$value}&";
        }
        $tplValue   = substr($tplValue, 0, -1);
        $params     = [
            'mobile'    => $phone,
            'tpl_id'    => $this->config->ls_tpl_id,
            'tpl_value' => strtotime($this->config->ls_create_at) < strtotime('2021-07-26') ? urlencode($tplValue) : $tplValue,
            'key'       => $smsKey,
        ];

        $response   = Curl::requestCurl($url, 'GET', $header = [], http_build_query($params));
        $result     = json_decode($response, true);
        $this->logs($phone, $params, $result);
        if (isset($result['error_code']) && $result['error_code'] == 0) {
            LotterySmsConfig::connect('main')
                ->where('ls_id', $this->config->ls_id)
                ->inc('ls_send_num', $result['result']['fee'])
                ->save();
            Db::name('smscode')
                ->insert([
                    's_phone'       => $phone,
                    's_content'     => json_encode($contents, 256),
                    's_expire_at'   => date('Y-m-d H:i:s', $this->time + $this->config->ls_expired_min * 60),
                    's_create_at'   => date('Y-m-d H:i:s', $this->time),
                ]);

            return ['status' => 1, 'msg' => 'success'];
        } else {
            return ['status' => 0, 'msg' => '短信发送异常'.$result['reason']];
        }
    }

    /**
     * @desc    发送短信
     * @param   string  $phone      手机号
     * @param   string  $area       国家代码
     * @param   array   $contents   短信内容
     * @return  array
     */
    public function sendIntl(string $phone, string $area, array $contents)
    {
        if (!is_array($contents) || empty($contents)) {
            return ['status' => 0, 'msg' => '短信内容格式错误'];
        }
        if ($check = $this->smsConfig()) {
            return $check;
        }

        $smsKey     = '883a836fee9124025cb2b6901dd4d813';
        $url        = 'http://v.juhe.cn/smsInternational/send.php';
        $tplValue   = '';
        foreach ($contents as $key => $value) {
            $tplValue .= "#{$key}#={$value}&";
        }
        $tplValue   = substr($tplValue, 0, -1);
        $params     = [
            'mobile'    => $phone,
            'areaNum'   => $area,
            'tplId'     => $this->config->ls_tpl_id,
            'tplValue'  => urlencode($tplValue),
            'key'       => $smsKey,
        ];

        $response   = Curl::requestCurl($url, 'GET', $header = [], http_build_query($params));
        $result     = json_decode($response, true);
        $this->logs($phone, $params, $result);
        if (isset($result['error_code']) && $result['error_code'] == 0) {
            LotterySmsConfig::connect('main')
                ->where('ls_id', $this->config->ls_id)
                ->inc('ls_send_num', $result['result']['fee'])
                ->save();
            Db::name('smscode')
                ->insert([
                    's_phone'       => $phone,
                    's_content'     => json_encode($contents, 256),
                    's_expire_at'   => date('Y-m-d H:i:s', $this->time + $this->config->ls_expired_min * 60),
                    's_create_at'   => date('Y-m-d H:i:s', $this->time),
                ]);

            return ['status' => 1, 'msg' => 'success'];
        } else {
            return ['status' => 0, 'msg' => '短信发送异常'.$result['reason']];
        }
    }

    /**
     * @desc 判断活动是否未开始或已结束
     */
    private function smsConfig()
    {
        $where  = $this->pid ? ['ls_pid' => $this->pid] : ['ls_appid' => $this->appId];
        $config = LotterySmsConfig::connect('main')->where($where)->find();
        if (!$config) {
            return ['status' => 0, 'msg' => 'APPID 或者 PID 错误，未匹配到短信活动.'];
        }
        if ($this->appSecret && $this->appSecret != $config->ls_secret) {
            return ['status' => 0, 'msg' => 'APPID 与 APP_SECRET 不匹配。'];
        }
        $this->config = $config;
        return 0;
    }

    /**
     * @desc    记录日志
     * @param   string  $phone  发送号码
     * @param   array   $params 发送参数
     * @param   array   $result 发送结果
     */
    private function logs($phone, $params, $result)
    {
        LotterySmsLogs::connect('main')
            ->create([
                'sl_phone'          => $phone,
                'sl_template_id'    => $this->config->ls_tpl_id,
                'sl_pid'            => $this->config->ls_pid,
                'sl_sid'            => isset($result['result']['sid'])  ? $result['result']['sid'] : '',
                'sl_body'           => json_encode($params, 256),
                'sl_response'       => json_encode($result, 256),
                'sl_num'            => isset($result['result']['fee'])  ? $result['result']['fee'] : 0,
                'sl_errcode'        => isset($result['error_code'])     ? $result['error_code'] : '',
            ]);
    }
}